<script setup>

import {
  reqAccountListByCondition,
  reqAddAccount,
  reqGetAllAccount,
  reqGiveRoles4Account,
  reqRemoveBatchAccountByIds,
  reqResetPasswordById,
  reqRoleIdsByAccountId,
} from "@/api/modules/account.js";
import {ref, watch} from "vue";
import api from "@/api/index.js";
import {ElMessage} from "element-plus";
import {md5} from "js-md5";
import {reqFileUpload} from "@/api/modules/file.js";
import {reqAllRoles} from "@/api/modules/role.js";
import PicUtil from "@/utils/PicUtil.js";
import {debounce} from "lodash";

const tableData = ref()
const tableIds = ref([])
const avatarList = ref([])

// 可以被勾选的行数据
const handleSelectable = (row) => {
  return !row.admin
}
// 收集被勾选的ids
const handleSelectionChange = (e) => {
  tableIds.value = e.map(item => item.uid)
}
const removeSelection = async () => {
  await reqRemoveBatchAccountByIds(tableIds.value)
  tableIds.value = []
  ElMessage.success('删除成功')
  await loadAccountList()
}

const showAdd = ref(false)
const defaultAddModel = {
  username: '',
  password: '',
  nickname: '默认用户',
  roleIds: [],
  avatar: ''
}

const imageURL = ref()
const addModel = ref(JSON.parse(JSON.stringify(defaultAddModel)))

const add = () => {
  showAdd.value = true
}

const confirmAdd = async () => {
  const addParams = JSON.parse(JSON.stringify(addModel.value))
  addParams.avatar = await reqFileUpload(uploadFile.value)
  addParams.password = md5(addModel.value.password)
  await reqAddAccount(addParams)
  ElMessage.success("保存成功")
  closeAdd()
  await loadAccountList()
}

const closeAdd = () => {
  showAdd.value = false
  addModel.value = JSON.parse(JSON.stringify(defaultAddModel))
  URL.revokeObjectURL(imageURL.value)
  imageURL.value = ''
}

const beforeAvatarUpload = (event) => {
  const suffix = PicUtil.getSuffix(event.name)
  if (!PicUtil.suffixList.includes(suffix)) {
    ElMessage.error("图片后缀名必须是png/jpg/jpeg")
    return false
  }
  if (!PicUtil.typeList.includes(event.type)) {
    ElMessage.error("图片格式不正确，请上传jpg/png类型的图片")
    return false
  }
}
const uploadFile = ref()
const uploadPic = async (event) => {
  uploadFile.value = event.file
  imageURL.value = URL.createObjectURL(event.file)
}


const showGiveRole = ref(false)
const giveRoleModel = ref({
  uid: '',
  roleIds: []
})
const fullCheck = ref(false)

// 监听选中的角色，判断目前是否全选
watch(() => giveRoleModel.value.roleIds, (newVal) => {
  if (!newVal || newVal.length === 0 || !roleList || roleList.value.length === 0) {
    fullCheck.value = false
  } else {
    fullCheck.value = newVal.length === roleList.value.length;
  }
})

// 分配角色时的全选按钮
const fullCheckBtn = () => {
  if (fullCheck.value) {
    giveRoleModel.value.roleIds = []
    fullCheck.value = false
  } else {
    giveRoleModel.value.roleIds = roleList.value.map(item => item.roleId)
    fullCheck.value = true
  }
}

// 展示分配角色弹出框
const giveRole = async (row) => {
  showGiveRole.value = true
  // 通过用户id，查询角色
  const roleIds = await reqRoleIdsByAccountId(row.uid)
  giveRoleModel.value.uid = row.uid
  giveRoleModel.value.roleIds = roleIds
}

// 保存为用户分配的角色
const confirmGiveRole = async () => {
  const {roleIds, uid} = giveRoleModel.value
  await reqGiveRoles4Account(roleIds, uid)
  closeGiveRole()
  ElMessage.success('分配角色成功')
}

// 关闭分配角色弹出框
const closeGiveRole = () => {
  showGiveRole.value = false
  giveRoleModel.value.roleIds = []
  giveRoleModel.value.uid = ''
}

// 是否显示重置密码弹出框
const showResetPassword = ref(false)

// 重置密码实体对象
const resetPasswordModel = ref({
  uid: '',
  username: '',
  password: '',
  confirmPassword: ''
})

// 显示重置密码弹出框
const handleResetPassword = (row) => {
  showResetPassword.value = true
  resetPasswordModel.value.uid = row.uid
  resetPasswordModel.value.username = row.username
}

// 重置密码确认按钮
const confirmResetPassword = async () => {
  const {uid, username, password, confirmPassword} = resetPasswordModel.value
  if (password !== confirmPassword) {
    ElMessage.error('两次输入密码不一致');
    return
  }
  // 发起更新密码请求
  const reqParams = {uid, username, password: md5(password)}
  await reqResetPasswordById(reqParams)
  ElMessage.success('重置密码成功')
  closeResetPassword()
}

// 关闭重置密码弹出框
const closeResetPassword = () => {
  showResetPassword.value = false
  resetPasswordModel.value = {}
}

// 加载用户列表
const loadAccountList = async () => {
  tableData.value = await reqAccountListByCondition(queryParams.value.like)
  avatarList.value = tableData.value.forEach(item => {
    item.avatar = api.fileDownloadURL + "/" + item.avatar
  })
}

const roleList = ref()
const queryParams=ref({
  like:''
})
// 加载角色信息
const loadAllRoles = async () => {
  roleList.value = await reqAllRoles();
}

const init = () => {
  loadAccountList()
  loadAllRoles()
}
init()
const loadRoleListDebounce=debounce(loadAccountList,500)
watch(()=>queryParams.value.like,()=>{
    loadRoleListDebounce()
})

</script>

<template>

  <!--  重置密码弹出框-->
  <el-dialog v-model="showResetPassword" @close="closeResetPassword" :show-close="false">
    <template #header>重置密码</template>
    <el-form label-width="80">
      <el-form-item disabled label="用户名">
        <el-input v-model="resetPasswordModel.username" disabled></el-input>
      </el-form-item>
      <el-form-item label="新密码">
        <el-input v-model="resetPasswordModel.password" type="password" show-password></el-input>
      </el-form-item>
      <el-form-item label="确认密码">
        <el-input v-model="resetPasswordModel.confirmPassword" type="password" show-password></el-input>
      </el-form-item>
      <el-form-item>
        <div style="text-align: center;width: 100%">
          <el-button type="primary" style="width: 80%" @click="confirmResetPassword">保存</el-button>
        </div>
      </el-form-item>
    </el-form>
  </el-dialog>

  <!--  分配角色弹出框-->
  <el-dialog v-model="showGiveRole" @close="closeGiveRole" :show-close="false">
    <template #header>
      分配角色
    </template>
    <el-form>
      <el-form-item>
        <el-button @click="fullCheckBtn">{{ !fullCheck ? '全选' : '取消全选' }}</el-button>
      </el-form-item>
      <el-form-item>
        <el-checkbox-group v-model="giveRoleModel.roleIds">
          <el-checkbox v-for="item of roleList" :key="item.roleId" :value="item.roleId"
                       :label="item.roleName"></el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item>
        <div style="text-align: center;width: 100%">
          <el-button type="primary" style="width: 80%" @click="confirmGiveRole">保存</el-button>
        </div>
      </el-form-item>
    </el-form>
  </el-dialog>

  <el-dialog v-model="showAdd" @close="closeAdd" :show-close="false">
    <template #header>
      新增用户
    </template>
    <el-form v-model="addModel" label-width="80px">
      <el-form-item prop="username" label="用户名">
        <el-input v-model="addModel.username"></el-input>
      </el-form-item>
      <el-form-item label="密码">
        <el-input v-model="addModel.password" type="password" show-password></el-input>
      </el-form-item>
      <el-form-item label="昵称">
        <el-input v-model="addModel.nickname"></el-input>
      </el-form-item>
      <el-form-item label="分配角色">
        <el-checkbox-group v-model="addModel.roleIds">
          <el-checkbox v-for="item of roleList" :key="item.roleId" :value="item.roleId"
                       :label="item.roleName"></el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item label="头像">
        <el-upload
            class="avatar-uploader"
            action="#"
            :http-request="uploadPic"
            :show-file-list="false"
            :before-upload="beforeAvatarUpload"
        >
          <div class="upload-pic" v-if="imageURL">
            <img :src="imageURL" class="avatar"/>
          </div>
          <div class="upload-pic" v-else>
            <el-icon class="avatar-uploader-icon">
              <Plus/>
            </el-icon>
          </div>
        </el-upload>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" style="width: 80%" @click="confirmAdd">保存</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>

  <!--  展示表格-->
  <el-card>
    <template #header>
      <el-form inline>
        <el-form-item>
          <el-button type="danger" :disabled="!tableIds || tableIds.length<=0" @click="removeSelection">删除选中
          </el-button>
        </el-form-item>
        <el-form-item>
          <el-button @click="add" type="primary">新增用户</el-button>
        </el-form-item>
        <el-form-item>
          <el-input v-model="queryParams.like" placeholder="用户名/昵称" clearable></el-input>
        </el-form-item>
      </el-form>
    </template>
    <el-table :data="tableData" show-overflow-tooltip class="table" @selection-change="handleSelectionChange">
      <el-table-column width="55" type="selection" :selectable="handleSelectable"/>
      <el-table-column prop="uid" label="ID"></el-table-column>
      <el-table-column prop="avatar" label="头像">
        <template #default="{row}">
          <el-image class="avatar" v-if="row.avatar" :src="row.avatar" hide-on-click-modal preview-teleported
                    :preview-src-list="[row.avatar]"></el-image>
        </template>
      </el-table-column>
      <el-table-column prop="username" label="用户名"></el-table-column>
      <el-table-column prop="nickname" label="昵称"></el-table-column>
      <el-table-column prop="lastLoginTime" label="上次登陆时间" width="140" sortable></el-table-column>
      <el-table-column prop="createTime" label="创建时间" width="120" sortable></el-table-column>
      <el-table-column label="操作" fixed="right" width="220">
        <template #default="{row}">
          <div v-if="!row.admin">
            <el-button @click="giveRole(row)">分配角色</el-button>
            <el-button @click="handleResetPassword(row)">重置密码</el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
  </el-card>

</template>
<style lang="scss" scoped>
.el-card {
  padding: 0;
  height: 100%;

  :deep .el-card__header {
    height: 50px;
    padding: 10px;
  }

  :deep .el-card__body {
    height: calc(100% - 50px);
    padding: 10px;

    .table {
      overflow: auto;
      height: 100%;

      .avatar {
        height: 40px;
      }
    }
  }
}

.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}

.avatar-uploader {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader:hover {
  border-color: var(--el-color-primary);
}

.avatar-uploader-icon, .upload-pic {
  font-size: 28px;
  color: #8c939d;
  width: 175px;
  height: 175px;
  text-align: center;
}
</style>
